package com.cy.pj.common.pool;

import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;


@Lazy //启动的时候不希望被创建对象，使用这个注解，表示默认延迟加载，描述的类的对象可以延迟创建
//何时需要何时创建（按需加载），还是会被读到内存，等于true延迟加载对象实例，fals启动时加载实例
@Component //这个类我们要交给spring来管理
/*@@Scope/*注解用于定义对象作用域，默认为单例（“Singleton”）作用域（一个JVM内存中名字相同的Bean只能有一个
 就是key相同的Bean(咋们说Sping中两大map，一个是存储配置信息的，一个是用来存储实例的，他其实都是通过map
 结构散列表形式存储，这个散列表就是我们说的哈希表，通过这个结构存储他需要一个key，就是bean的名字) ）,
 @Scope("prototype")表示多例作用域对象，每次需要这个对象spring再帮你创建一份，
 此类实例与Lazy无关，默认何时需要何时创建，并且不会存储到sping对象池容器中的。

这个类该采用怎样的一种设计机制，在内存中更加科学的运行？

其中，在上面的代码中，我们使用了@Sope注解对类进行描述用于指定类的实例作用域，
默认是单例（singleton）作用域，配合延迟加载@Lazy特性使用，表示此类的实例在
需要时可以创建一份并且将其存储到spring容器中（Bean）池，需要的时候从池中去，
以实现对象的可重用。假如一些对象应用的次数非常少，可以考虑不放入池中，
进而使用@Scope（“prototype”）作用域对类进行描述，让此类的对象何时需要何时创建，
用完以后当此对象不可达了，则可以直接被GC系统销毁

对象生命周期方法
程序中的每个对象都有生命周期，对象创建，初始化，应用，销毁的这个过程称之为对象的生命周期。在对象创建
以后要初始化，应用完成以后要销毁时执行的一些方法，我们可以称之为生命周期方法。但不见得每个对象都会定
义生命周期方法。在实际项目中往往一些池对象通常会定义这样的一些生命周期方法(例如连接池)。那这样的方法
在spring工程中如何进行标识呢？通常要借助@PostConstruct和@PreDestroy注解对特定方法进行描述

1)@PostConstruct 注解描述的方法为生命周期初始化方法,在对象构建以后执行.
2)@PreDestroy 注解描述的方法为生命周期销毁方法,此方法所在的对象,假如存储到了spring容器,那这个对象
在从spring容器移除之前会先执行这个生命周期销毁方法(prototype作用域对象不执行此方法).
*/
public class ObjectPool {
    public ObjectPool() { //运行启动类看构造了没

        System.out.println("ObjectPool");
    }
    @PostConstruct//表示对象构建之后执行这个方法
    public void init(){
        System.out.println("init()");
    }
    @PreDestroy//销毁之前执行，将来要把池里的对象移除就要调用predestroy方法
    public void destory(){
        System.out.println("destroy()");
    }

}
